package com.groupbuying.customer.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.StringUtils;
import com.alipay.api.response.AlipaySystemOauthTokenResponse;
import com.aliyun.openservices.ons.api.Message;
import com.aliyun.openservices.ons.api.Producer;
import com.google.common.base.Strings;
import com.groupbuying.customer.connector.CurrencyFeign;
import com.groupbuying.customer.connector.SysconfigFeign;
import com.groupbuying.customer.constants.*;
import com.groupbuying.customer.connector.WechatAliFeign;
import com.groupbuying.customer.constants.CommonConstants;
import com.groupbuying.customer.constants.CustomerAliinfoRelEnumConstants;
import com.groupbuying.customer.constants.CustomerAliinfoRelSearchConstants;
import com.groupbuying.customer.constants.CustomerAlipayConstants;
import com.groupbuying.customer.dao.CustomerAliinfoRelDao;
import com.groupbuying.customer.dao.CustomerUshopDao;
import com.groupbuying.customer.domain.CustomerAliinfoRelDO;
import com.groupbuying.customer.domain.CustomerDO;
import com.groupbuying.customer.domain.CustomerUshopDO;
import com.groupbuying.customer.domain.UserToken;
import com.groupbuying.customer.mq.CustomerMQConfig;
import com.groupbuying.customer.service.CustomerAliinfoRelService;
import com.groupbuying.customer.service.CustomerService;
import com.groupbuying.customer.utils.AliUntil;
import com.groupbuying.customer.utils.JwtUtils;
import com.groupbuying.customer.utils.apiresult.ApiResult;
import com.groupbuying.customer.utils.apiresult.ApiResultCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Service
public class CustomerAliinfoRelServiceImpl implements CustomerAliinfoRelService {
    private static final Logger logger = LoggerFactory.getLogger(CustomerAliinfoRelServiceImpl.class);
    @Autowired
    private CustomerAliinfoRelDao customerAliinfoRelDao;
    @Autowired
    private SysconfigFeign sysconfigFeign;
    @Autowired
    CustomerUshopDao customerUshopDao;
    @Autowired
    private Producer producer;
    @Autowired
    private WechatAliFeign wechatAliFeign;
    @Autowired
    private CurrencyFeign currencyFeign;
    @Autowired
    private CustomerService customerService;



    @Override
    public CustomerAliinfoRelDO get(String customerId) {
        return customerAliinfoRelDao.get(customerId);
    }

    @Override
    public List<CustomerAliinfoRelDO> list(Map<String, Object> map) {
        return customerAliinfoRelDao.list(map);
    }

    @Override
    public int count(Map<String, Object> map) {
        return customerAliinfoRelDao.count(map);
    }

    @Override
    public int save(CustomerAliinfoRelDO customerAliinfoRel) {
        return customerAliinfoRelDao.save(customerAliinfoRel);
    }

    @Override
    public int update(CustomerAliinfoRelDO customerAliinfoRel) {
        return customerAliinfoRelDao.update(customerAliinfoRel);
    }

    @Override
    public int updateByAliUserId(CustomerAliinfoRelDO customerAliinfoRel) {
        return customerAliinfoRelDao.updateByAliUserId(customerAliinfoRel);
    }

    @Override
    public int remove(String customerId) {
        return customerAliinfoRelDao.remove(customerId);
    }

    @Override
    public int batchRemove(String[] customerIds) {
        return customerAliinfoRelDao.batchRemove(customerIds);
    }

    @Override
    public ApiResult customerAliRegister(String authCode) {
        try {
            //调用支付宝授权登录Feign接口
            Map<String, String> map = wechatAliFeign.aliGetUserIdAccessCodeByAuthCode(authCode, "youdianproductor");
            if (map == null) {
                return ApiResult.failure("支付宝小程序通过authCode获取accessToken和alipayUserId为空");
            }
            //获取accesstoken
            String accessToken = map.get("accessToken");
            //获取aliPayUserId
            String aliPayUserId = map.get("alipayUserId");
            logger.info("accessToken为:{}，aliPayUserId为:{}", accessToken, aliPayUserId);
            Map<String, Object> parma = new HashMap<>();
            parma.put(CustomerAliinfoRelSearchConstants.SEARCH_ALIPAYUSERID, aliPayUserId);
            List<CustomerAliinfoRelDO> customerAliinfoRelDOS = customerAliinfoRelDao.list(parma);
            CustomerUshopDO customerUshopDO = new CustomerUshopDO();

            //传输数据容器
            Map<String, Object> data = new HashMap<>();
            if (customerAliinfoRelDOS == null || customerAliinfoRelDOS.size() == 0) {
                //创建子平台账户
                customerUshopDO.setCustomerId(sysconfigFeign.getCustomerID());
                customerUshopDO.setGmtCreate(new Date());
                customerUshopDO.setGmtModified(new Date());
                customerUshopDO.setIsDelete(CustomerAliinfoRelEnumConstants.ENUM_ISDELETE_UNDEL);
                customerUshopDO.setMainUuid("");
				customerUshopDao.save(customerUshopDO);

                //创建支付宝关系
                //AlipayUserInfoShareResponse userInfo = AliUntil.getUserInfo(accessToken,param);
                CustomerAliinfoRelDO ustomerAliinfoRelDO = new CustomerAliinfoRelDO();
                ustomerAliinfoRelDO.setCustomerId(customerUshopDO.getCustomerId());
                ustomerAliinfoRelDO.setIsDelete(CustomerAliinfoRelEnumConstants.ENUM_ISDELETE_UNDEL);
                ustomerAliinfoRelDO.setGmtCreate(new Date());
                ustomerAliinfoRelDO.setGmtModified(new Date());
				/*ustomerAliinfoRelDO.setAvatarUrl(userInfo.getAvatar());
				ustomerAliinfoRelDO.setCity(userInfo.getCity());
				ustomerAliinfoRelDO.setCountry(userInfo.getCountryCode());
				ustomerAliinfoRelDO.setGender(userInfo.getGender());
				ustomerAliinfoRelDO.setIsCertified(userInfo.getIsCertified());
				ustomerAliinfoRelDO.setIsStudentCertified(userInfo.getIsStudentCertified());
				ustomerAliinfoRelDO.setNickName(userInfo.getNickName());
				ustomerAliinfoRelDO.setProvince(userInfo.getProvince());
				ustomerAliinfoRelDO.setUserStatus(userInfo.getUserStatus());
				ustomerAliinfoRelDO.setUserType(userInfo.getUserType());*/
                ustomerAliinfoRelDO.setAlipayUserid(aliPayUserId);
				customerAliinfoRelDao.save(ustomerAliinfoRelDO);

//                //保存数据存入容器中
//                data.put("customer", customerUshopDO);
//                data.put("alipayRel", ustomerAliinfoRelDO);
//
//                try {
//                    sendMsgToMQ(data, CustomerMQConfig.TAG_CUSTOMER_ALIPAY_REGISTER_NEW);
//                    logger.error("支付宝新增用户发送MQ成功");
//                } catch (Exception e) {
//                    logger.error("支付宝新增用户发送MQ失败，采用本地直接入库");
//                    customerUshopDao.save(customerUshopDO);
//                    customerAliinfoRelDao.save(ustomerAliinfoRelDO);
//                }

            } else {
                logger.info("用户已存在");
                CustomerAliinfoRelDO customerAliinfoRelDO = customerAliinfoRelDOS.get(0);
                customerUshopDO = customerUshopDao.get(customerAliinfoRelDO.getCustomerId());
            }
            Map result = new HashMap();
            //授权
            UserToken userToken = new UserToken(customerUshopDO.getMobile(), customerUshopDO.getCustomerId(), "");//过期天数
            String token = JwtUtils.generateToken(userToken, CommonConstants.COMMON_TOKEN_DAY * 24 * 60 * 60 * 1000);
            result.put("token", token);
            if (!Strings.isNullOrEmpty(customerUshopDO.getMobile())) {
                result.put("mobile", customerUshopDO.getMobile());
            }
            return ApiResult.success(ApiResultCode.SUCCESS_LOGIN, result);

        } catch (AlipayApiException e) {
            e.printStackTrace();

        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return ApiResult.failure("获取access_token失败");
    }

    /**
     * //通过用户ID获取支付宝用户userId
     *
     * @param customerId
     * @return java.lang.String
     * @Author Vincentxin
     * @Date 2019/10/24 11:05
     **/
    @Override
    public String getAliUserIdByCustomerId(String customerId) {
        String aliUserId = "";
        try {
            aliUserId = customerAliinfoRelDao.getAliUserIdByCustomerId(customerId);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return aliUserId;
    }


    /**
     * //支付宝用户手机号授权注册登录接口
     *
     * @param //authcode       支付宝用户授权code
     * @param //encryptedData  支付宝用户授权手机号加密信息
     * @param //支付宝用户授权code
     * @param //支付宝用户授权手机号加密信息
     * @return com.groupbuying.customer.utils.apiresult.ApiResult
     * @Author Vincentxin
     * @Date 2019/9/27 11:57
     **/
    @Override
    @Transactional
    public ApiResult regiestForAli(Map<String, String> preParam) {
        logger.info("前端传递的参数：{}", preParam);
        String authCode = preParam.get("authcode");
        String encryptedData = preParam.get("encryptedData");
        preParam.put("indicate", "youdianproductor");
        logger.info("前端传递的参数，用户授权code:{}，用户手机号加密信息：{}", authCode, encryptedData);
        Map<String, Object> map = new HashMap<>();
        Map<String, Object> mqParams = new HashMap<>();
        try {
            //调用支付宝授权登录Feign接口
            Map<String, String> maps = wechatAliFeign.aliGetUserIdAccessCodeByAuthCode(authCode, "youdianproductor");
            if (maps == null) {
                return ApiResult.failure(ApiResultCode.AUTHORIZATIONFAILURE, "支付宝小程序通过authCode获取accessToken和alipayUserId为空");
            }
            //获取accesstoken
            String accessToken = maps.get("accessToken");
            //获取aliPayUserId
            String aliPayUserId = maps.get("alipayUserId");

            logger.info("获取支付宝accessToken:{},aliPayUserId:{}", accessToken, aliPayUserId);
            //3.这一步是解密用户手机号
            //调用支付宝解密手机号Feign接口
            Map<String, String> result = wechatAliFeign.aliDecodeUserEncryptedData(preParam);
            if (result == null || StringUtils.isEmpty(result.get("mobile"))) {
                logger.error("用户手机号解密失败");
                return ApiResult.failure("手机号获取失败");
            }
            //电话号
            String phone = result.get("mobile");

            logger.info("获取支付宝用户手机号:{}", phone);
            //异步传输对象容器
            Map<String, Object> data = new HashMap<>();
            CustomerAliinfoRelDO customerAliinfoRel = customerAliinfoRelDao.getAliByalipayuserId(aliPayUserId);
            logger.info("获取支付宝关联CustomerAliinfoRelDao:{}", customerAliinfoRel);
            CustomerUshopDO customerUshopDO = new CustomerUshopDO();
            boolean isNewCur = false;
            //判断是否存在不存在代表用户没有注册
            if (customerAliinfoRel == null) {
                //创建主账号平台
                customerUshopDO.setCustomerId(sysconfigFeign.getCustomerID());
                customerUshopDO.setGmtCreate(new Date());
                customerUshopDO.setGmtModified(new Date());
                customerUshopDO.setIsDelete(CommonConstants.COMMON_FLAG_UNDEL);
                customerUshopDO.setType(CommonConstants.MLS);
                customerUshopDO.setMobile(phone);
                customerUshopDO.setMainUuid("");
                customerUshopDao.save(customerUshopDO);
                logger.info("创建U店信息为:{}", customerUshopDO);
                //创建支付宝与用户关系
                CustomerAliinfoRelDO customerAliinfoRelDO = new CustomerAliinfoRelDO();
                customerAliinfoRelDO.setCustomerId(customerUshopDO.getCustomerId());
                customerAliinfoRelDO.setIsDelete(CommonConstants.COMMON_FLAG_UNDEL);
                customerAliinfoRelDO.setGmtCreate(new Date());
                customerAliinfoRelDO.setGmtModified(new Date());
                customerAliinfoRelDO.setAlipayUserid(aliPayUserId);
                customerAliinfoRelDao.save(customerAliinfoRelDO);
                logger.info("绑定阿里信息为:{}", customerAliinfoRelDO);
//                data.put("customer", customerUshopDO);
//                data.put("alipayRel", customerAliinfoRelDO);
//                logger.info("MQ消息体为:{}", data);
                //发送保存对象到mq中
                //TODO 需要添加mq
//                try {
//                    sendMsgToMQ(data, CustomerMQConfig.TAG_CUSTOMER_ALIPAY_REGISTER_NEW);
//                    logger.info("用户新增发送到Mq成功，用户ID:{}", customerUshopDO.getCustomerId());
//                } catch (Exception e) {
//                    logger.error("新增用户发送MQ失败，采用本地直接入库");
//                    customerUshopDao.save(customerUshopDO);
//                    customerAliinfoRelDao.save(customerAliinfoRelDO);
//                }
            } else {
                //关系表存在该用户id，证明用户已注册
                String customerId = customerAliinfoRel.getCustomerId();
                //通过customerId获取当前已注册用户关联信息对应的主表信息
                customerUshopDO = customerUshopDao.get(customerId);
                logger.info("获取优店表对应用户信息为:{}", customerUshopDO);
                //获取当前已注册用户主表的手机号
                String mobile = customerUshopDO.getMobile();
                logger.info("获取优店表对应手机号为:{}", mobile);
                boolean flag = false; //是否需要修改数据库
                //判断当前已注册用户主表的手机号是否存在且更新了
                if (StringUtils.isEmpty(mobile)) {
                    logger.error("已注册手机号为空");
                    //当前注册用户主表的手机号为空，查询主表中是否有相同的手机号注册过。
                    CustomerUshopDO customerUshopDO1 = customerUshopDao.getUshopByMobile(phone);
                    logger.info("支付宝授权手机好查询用户表中是否存在注册过的手机号:{}", customerUshopDO1);
                    //主表中没有当前支付宝授权解析的手机号注册用户
                    if (customerUshopDO1 == null) {
                        logger.info("支付宝授权的手机号在用户表中没有注册没有关联");
                        //更新当前注册用户的主表手机号
                        customerUshopDO.setMobile(phone);
                        customerUshopDO.setGmtModified(new Date());
                        //TODO 保存后需要改为mq异步发送
                        customerUshopDao.update(customerUshopDO);
                        logger.info("当前注册授权为新建立的，更新手机号完成:{}", customerUshopDO);
                        //TODO 注册积分账户
                        Map searchMap = new HashMap();
                        searchMap.put(CustomerUshopSearchConstants.SEARCH_CUSTOMERID, customerUshopDO.getCustomerId());
                        Map res = currencyFeign.createCurrencyCustomer(searchMap);
                        if (res.size() > 0) {
                            isNewCur = true;
                        }


                    } else {
                        //主表中存在当前支付宝授权解析的手机号注册的其他用户，将当前支付宝注册用户的关联信息与主表进行关联。
                        logger.info("当前授权手机号在主表中存在注册：{}", customerUshopDO1);
                        customerAliinfoRel.setCustomerId(customerUshopDO1.getCustomerId());
                        customerAliinfoRel.setGmtModified(new Date());
                        try {
                            customerAliinfoRelDao.updateByAliUserId(customerAliinfoRel);
                        } catch (DuplicateKeyException e) {
                            customerAliinfoRelDao.remove(customerUshopDO1.getCustomerId());
                            customerAliinfoRelDao.updateByAliUserId(customerAliinfoRel);
                        }
                        //这么写的目的是让用户切换，然后生成token与代码逻辑统一
                        customerUshopDO = customerUshopDO1;

                    }
                }
                //如果信息有修改
//                if (flag) {
//                    //发送修改对象到mq中
//                    data.put("customer", customerUshopDO);
//                    logger.info("MQ消息体为:{}", data);
//                    try {
//                        sendMsgToMQ(data, CustomerMQConfig.TAG_CUSTOMER_PHONE_UPDATE);
//                    } catch (Exception e) {
//                        logger.error("更新用户信息发送MQ失败，采用本地直接入库");
//                        customerUshopDao.update(customerUshopDO);
//                    }
//                }
            }
            List<CustomerDO> customers = customerService.getCustomerByMobile(phone);
            if (customers.size() == 0){
                //发送mq到老够样
                try {
                    mqParams.put("userName", phone);
                    mqParams.put("mobile", phone);
                    mqParams.put("password", phone.substring(phone.length()-6));
                    Message message = new Message(CustomerMQConfig.GY_TOPIC, CustomerMQConfig.MOBILE_REGISTERED, JSON.toJSONString(mqParams, SerializerFeature.DisableCircularReferenceDetect).getBytes());
                    producer.send(message);
                    logger.info("mq发送成功");
                } catch (Exception e) {
                    e.printStackTrace();
                    logger.error("mq发送失败：{}",e.getMessage());
                }
            }
            try {
                UserToken userToken = new UserToken(customerUshopDO.getMobile(), customerUshopDO.getCustomerId(), "");
                String token = JwtUtils.generateToken(userToken, CommonConstants.COMMON_TOKEN_DAY * 24 * 60 * 60 * 1000);
                map.put("token", token);
                map.put("mobile", phone);
                map.put("giftCur", isNewCur == true ? "10" : "");
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("Token 生成失败");
                return ApiResult.failure("token获取失败");
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
        return ApiResult.success(ApiResultCode.SUCCESS_LOGIN, map);
    }

    /**
     * 发送的用户中心消费模块的工具方法。
     *
     * @param obj 消息传递对象
     */
    private void sendMsgToMQ(Object obj, String tag) throws Exception {
        //创建子账号平台
        Message orderMessage = new Message(CustomerMQConfig.TOPIC, tag,
                JSON.toJSONString(obj, SerializerFeature.DisableCircularReferenceDetect).getBytes());
        producer.send(orderMessage);
    }

}
